#pragma once

#include <iostream>
#include <pthread.h>
#include <unordered_set>
#include <string>
#include <fstream>
#include <cassert>
#include <mariadb/mysql.h>
#include <jsoncpp/json/json.h>
#include <memory>

#include "../comm/log.hpp"
#include "../comm/util.hpp"
#include "../comm/httplib.h"
#include "../comm/sqliteManager.hpp"

namespace ns_users
{
    using std::string;
    const string users_list = "./users/users.list";
    using namespace ns_util;
    using namespace ns_log;

    class Users
    {
    private:
        std::unordered_set<int> _admins; // 管理员
        std::unordered_set<int> _users;  // 用户

        pthread_mutex_t _mutex;
        SQLiteManager dbManager; // 数据库管理器

    public:
        Users(const std::string &dbName) : dbManager(dbName)
        {
            pthread_mutex_init(&_mutex, nullptr);
            if (!dbManager.openDatabase())
            {
                std::cerr << "无法打开数据库 " << dbManager.getErrorMessage() << std::endl;
            }
            LOG(DEBUG) << "初始化用户管理器" << std::endl;
        }

        ~Users()
        {
            pthread_mutex_destroy(&_mutex);
            dbManager.closeDatabase();
        }

        Users()
        { // 初始化互斥锁
            pthread_mutex_init(&_mutex, nullptr);
        }

        // sqlite版本
        // 判断用户是否存在
        bool isUserExist(const std::string &username)
        {

            std::string query = "SELECT username FROM users WHERE username = '" + username + "';";
            auto results = dbManager.executeSelect(query);

            return !results.empty() && !results[0].empty();
        }

        // 注销函数
        bool logoff(const std::string &username)
        {
            // 查询是否存在指定用户名的用户
            std::string query = "SELECT username FROM users WHERE username = '" + username + "';";
            auto results = dbManager.executeSelect(query);

            // 检查用户是否存在
            if (!results.empty() && results[0].size() >= 1)
            {
                query = "delete from users where username = '" + username + "';";
                dbManager.executeQuery(query);
                // 用户存在，记录注销日志
                LOG(DEBUG) << "注销成功，用户: " << username << std::endl;
                // 这里可以添加清除用户会话的逻辑，例如更新数据库状态或删除会话数据
                return true;
            }
            else
            {
                LOG(DEBUG) << "注销失败，用户不存在: " << username << std::endl;
                return false;
            }
        }


        // 登录函数
        bool login(const std::string &username, const std::string &password, const std::string &email)
        {
            // 查询是否存在指定用户名的用户
            std::string query = "SELECT password, email FROM users WHERE username = '" + username + "';";
            auto results = dbManager.executeSelect(query);

            // 检查用户是否存在
            if (!results.empty() && results[0].size() >= 2)
            {
                // 用户存在，提取存储的密码和电子邮件
                std::string storedPassword = results[0][0]; // 第0列是password
                std::string storedEmail = results[0][1];    // 第1列是email
                LOG(INFO) << "数据库信息: " << "密码: " << storedPassword << " " << "电子邮件:" << storedEmail << std::endl;

                // 验证密码和电子邮件
                if (storedPassword == password && storedEmail == email)
                {
                    LOG(DEBUG) << "登录成功" << std::endl;
                    return true;
                }
                else
                {
                    LOG(DEBUG) << "登录失败, 信息不匹配" << std::endl;
                    return false;
                }
            }
            else
            {
                LOG(DEBUG) << "登录失败, 用户不存在" << std::endl;
                return false;
            }
        }

        bool registerUser(const std::string &username, const std::string &password, const std::string &email, std::string &resp)
        {
            LOG(DEBUG) << "开始注册用户" << std::endl;
            // 检查用户名是否已经存在
            std::string checkUsernameQuery = "SELECT 1 FROM users WHERE username = '" + username + "';";
            auto usernameResults = dbManager.executeSelect(checkUsernameQuery);

            if (!usernameResults.empty())
            {
                // 用户名已存在
                resp = "注册失败，用户名已存在";
                return false;
            }

            // 检查邮箱是否已经存在
            std::string checkEmailQuery = "SELECT 1 FROM users WHERE email = '" + email + "';";
            auto emailResults = dbManager.executeSelect(checkEmailQuery);

            if (!emailResults.empty())
            {
                // 邮箱已存在
                resp = "注册失败，邮箱已存在";
                return false;
            }

            LOG(DEBUG) << username << " " << password << " " << email << std::endl;
            // 用户名和邮箱都不存在，执行插入操作
            std::string insertQuery = "INSERT INTO users (username, password, email) VALUES ('" + username + "', '" + password + "', '" + email + "');";
            bool success = dbManager.executeQuery(insertQuery);

            if (success)
            {
                LOG(INFO) << "注册用户成功" << std::endl;
                resp = "注册成功";
                return true;
            }
            else
            {
                resp = "注册失败，数据库错误";
                return false;
            }

            return true;
        }

        // 获取用户信息
        Json::Value getUserInfo(const std::string &username)
        {
            LOG(DEBUG) << "getUserInfo代码执行" << "\n";
            Json::Value userInfo;

            // 查询用户信息
            std::string query = "SELECT * FROM users WHERE username = '" + username + "';";
            auto results = dbManager.executeSelect(query);
            std::string errMsg = dbManager.getErrorMessage();
            if (!errMsg.empty())
            {
                LOG(ERROR) << "查询用户信息失败: " << errMsg << std::endl;
                userInfo["error"] = errMsg;
                return userInfo;
            }

            // 检查用户是否存在
            if (!results.empty() && !results[0].empty())
            {
                // 用户存在，提取存储的信息
                if (results[0].size() > 0)
                    userInfo["id"] = results[0][0];
                if (results[0].size() > 1)
                    userInfo["username"] = results[0][1];
                if (results[0].size() > 2)
                    userInfo["password"] = results[0][2];
                if (results[0].size() > 3)
                    userInfo["email"] = results[0][3];
                if (results[0].size() > 4)
                    userInfo["phone"] = results[0][4];
                if (results[0].size() > 5)
                    userInfo["gender"] = results[0][5];
                if (results[0].size() > 6)
                    userInfo["description"] = results[0][6];
            }
            else
            {
                // 用户不存在
                userInfo["error"] = "用户不存在";
            }

            // LOG(DEBUG) << "获取用户信息: " << userInfo.toStyledString() << std::endl;
            return userInfo;
        }

        // 更新用户信息
        bool updateUserInfo(const std::string &username, const Json::Value &newInfo, std::string &resp) {
            LOG(DEBUG) << "updateUserInfo代码执行" << "\n";
            
            // 检查用户是否存在
            Json::Value userInfo = getUserInfo(username);
            if (userInfo.isMember("error")) {
                resp = userInfo["error"].asString();
                return false;
            }

            // 构建更新语句
            std::string updateQuery = "UPDATE users SET ";
            bool first = true;

            if (newInfo.isMember("password")) {
                updateQuery += "password = '" + newInfo["password"].asString() + "'";
                first = false;
            }
            if (newInfo.isMember("email")) {
                if (!first) updateQuery += ", ";
                updateQuery += "email = '" + newInfo["email"].asString() + "'";
                first = false;
            }
            if (newInfo.isMember("phone")) {
                if (!first) updateQuery += ", ";
                updateQuery += "phone = '" + newInfo["phone"].asString() + "'";
                first = false;
            }
            if (newInfo.isMember("gender")) {
                if (!first) updateQuery += ", ";
                std::string gender = newInfo["gender"].asString();
                if (gender == "男") {
                    gender = "Male";
                } else if (gender == "女") {
                    gender = "Female";
                } else {
                    gender = "Other";
                }
                updateQuery += "gender = '" + gender + "'";
                first = false;
            }
            if (newInfo.isMember("description")) {
                if (!first) updateQuery += ", ";
                updateQuery += "description = '" + newInfo["description"].asString() + "'";
            }

            updateQuery += " WHERE username = '" + username + "';";

            // 执行更新
            if (dbManager.executeQuery(updateQuery)) {
                std::cout << "用户信息更新成功!" << std::endl;
                return true;
            } else {
                resp = "更新失败: " + dbManager.getErrorMessage();
                LOG(ERROR) << "更新用户信息失败: " << resp << std::endl;
                return false;
            }
        }

        // --------------------------------------------------------- //
        // 判断用户是否存在
        bool isUserExistFileVersion(const std::string &username)
        {
            std::ifstream file(users_list);

            if (!file.is_open())
            {
                std::cerr << "Error opening file: " << users_list << std::endl;
                return false;
            }

            std::string line;
            while (std::getline(file, line))
            {
                std::vector<std::string> parts;
                StringUtil::SplitString(line, &parts, " "); // 使用你提供的 SplitString 函数分割字符串

                if (parts.size() >= 2 && parts[0] == username)
                {
                    file.close();
                    return true; // 找到用户名
                }
            }

            file.close();
            return false; // 用户名未找到
        }

        // 登录函数
        bool loginFileVersion(const std::string &username, const std::string &password)
        {
            std::ifstream file(users_list);

            if (!file.is_open())
            {
                std::cerr << "Error opening file: " << users_list << std::endl;
                return false;
            }

            std::string line;
            while (std::getline(file, line))
            {
                std::vector<std::string> parts;
                StringUtil::SplitString(line, &parts, " "); // 使用你提供的 SplitString 函数分割字符串

                if (parts.size() >= 2 && parts[0] == username && parts[1] == password)
                {
                    LOG() << "登录成功, 用户存在" << "\n";
                    file.close();
                    return true; // 用户名和密码匹配
                }
            }

            LOG() << "登录失败, 用户不存在" << "\n";
            file.close();
            return false; // 用户名或密码不匹配或未找到
        }

        // 注册用户函数
        bool registerUserFileVersion(const std::string &username, const std::string &password, std::string &resp)
        {
            std::ofstream file(users_list, std::ios_base::app); // 以追加模式打开文件

            if (!file.is_open())
            {
                std::cerr << "Error opening file: " << users_list << std::endl;
                return false;
            }

            if (isUserExist(username))
            {
                resp = "用户名已存在";
                std::cerr << "Error: " << resp << std::endl;
                file.close();
                return false;
            }

            // 写入新用户信息
            file << username << " " << password << std::endl;

            file.close();
            std::cout << "用户注册成功!" << std::endl;
            return true;
        }
    };
}